import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Color;
import java.awt.Component;
import java.awt.Desktop;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Vector;

import javax.swing.BoxLayout;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextField;
import javax.swing.ListSelectionModel;
import javax.swing.SwingConstants;
import javax.swing.border.LineBorder;


public class MainWindow {

	private JFrame frmHelpingLily;
	private JTextField wellRowCount;
	private JTextField wellColumnCount;
	private JTextField statusField;
	private JTextField fileNameField;
	private JTextField directoryField;
	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			@Override
			public void run() {
				try {
					MainWindow window = new MainWindow();
					window.frmHelpingLily.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the application.
	 * @throws IOException 
	 */
	public MainWindow() throws IOException {
		initialize();
	}

	/**
	 * Initialize the contents of the frame.
	 */
	private void initialize() throws IOException {
		try {
			new File(new File(".").getCanonicalPath() + File.separator + "config").mkdir();
		} catch (IOException e2) {
			// TODO Auto-generated catch block
			e2.printStackTrace();
		}
		
		frmHelpingLily = new JFrame();
		frmHelpingLily.setTitle("Helping Lily!");
		frmHelpingLily.setBounds(100, 100, 730, 482);
		frmHelpingLily.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

		frmHelpingLily.getContentPane().setLayout(new BorderLayout(0, 0));

		final JPanel buttonPanel = new JPanel();
		buttonPanel.setBorder(new LineBorder(new Color(0, 0, 0), 2));
		frmHelpingLily.getContentPane().add(buttonPanel, BorderLayout.CENTER);
		final GridLayout buttonPanelLayout;
		Integer wellRows = 8;
		Integer wellColumns = 12;
		buttonPanel.setLayout(buttonPanelLayout = new GridLayout(wellRows, wellColumns, 0, 0));
		final Vector<WellCheckBox> allCheckboxes = new Vector<WellCheckBox>(); 


		for(int i=1; i<=wellRows; i++){
			for(int j=1;j<=wellColumns;j++){
				Integer checkBoxNumber = (i-1)*wellColumns+j;
				WellCheckBox checkBox = new WellCheckBox("checkBox_",checkBoxNumber,i,j);
				buttonPanel.add(checkBox);
				allCheckboxes.add(checkBox);
			}
		}

		JMenuBar menuBar = new JMenuBar();
		frmHelpingLily.getContentPane().add(menuBar, BorderLayout.NORTH);

		JMenu fileMenu = new JMenu("File");
		menuBar.add(fileMenu);

		JMenuItem exitMenuItem = new JMenuItem("Exit");
		exitMenuItem.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				System.exit(0);
			}
		});
		
		JMenuItem mntmNewMenuItem = new JMenuItem("New Configuration");

		fileMenu.add(mntmNewMenuItem);
		
		JMenuItem mntmOpenConfiguration = new JMenuItem("Open Configuration");

		fileMenu.add(mntmOpenConfiguration);
		
		JMenuItem mntmSaveConfiguration = new JMenuItem("Save Configuration");

		fileMenu.add(mntmSaveConfiguration);


		fileMenu.add(exitMenuItem);

		JMenu selectMenu = new JMenu("Select");
		menuBar.add(selectMenu);

		JMenuItem selectAllMenuItem = new JMenuItem("Select All");
		selectMenu.add(selectAllMenuItem);

		JMenuItem deselectAllMenuItem = new JMenuItem("Deselect all");
		selectMenu.add(deselectAllMenuItem);

		final String DEFAULT_STATUS = "Waiting for file...";
		final String DEFAULT_DIRECTORY = "C:\\Users\\"+System.getenv("USERNAME")+"\\Desktop\\";

		JTabbedPane optionsPane = new JTabbedPane(SwingConstants.TOP);
		frmHelpingLily.getContentPane().add(optionsPane, BorderLayout.EAST);

		JPanel fileOptionsPanel = new JPanel();
		optionsPane.addTab("File Options", null, fileOptionsPanel, null);
		GridBagLayout gbl_fileOptionsPanel = new GridBagLayout();
		gbl_fileOptionsPanel.columnWidths = new int[]{46, 97, 0, 0, 23, 0};
		gbl_fileOptionsPanel.rowHeights = new int[]{0, 20, 14, 23, 0, 0, 0};
		gbl_fileOptionsPanel.columnWeights = new double[]{1.0, 1.0, 0.0, 0.0, 0.0, Double.MIN_VALUE};
		gbl_fileOptionsPanel.rowWeights = new double[]{0.0, 0.0, 0.0, 0.0, 1.0, 0.0, Double.MIN_VALUE};
		fileOptionsPanel.setLayout(gbl_fileOptionsPanel);

		JLabel lblFilename = new JLabel("File Name");
		GridBagConstraints gbc_lblFilename = new GridBagConstraints();
		gbc_lblFilename.anchor = GridBagConstraints.WEST;
		gbc_lblFilename.insets = new Insets(0, 0, 5, 5);
		gbc_lblFilename.gridx = 0;
		gbc_lblFilename.gridy = 0;
		fileOptionsPanel.add(lblFilename, gbc_lblFilename);

		fileNameField = new JTextField();
		fileNameField.setText("Results");
		GridBagConstraints gbc_fileNameField = new GridBagConstraints();
		gbc_fileNameField.gridwidth = 2;
		gbc_fileNameField.fill = GridBagConstraints.HORIZONTAL;
		gbc_fileNameField.insets = new Insets(0, 0, 5, 5);
		gbc_fileNameField.gridx = 1;
		gbc_fileNameField.gridy = 0;
		fileOptionsPanel.add(fileNameField, gbc_fileNameField);
		fileNameField.setColumns(10);

		JLabel lblDirectory = new JLabel("Directory");
		lblDirectory.setHorizontalAlignment(SwingConstants.LEFT);
		GridBagConstraints gbc_lblDirectory = new GridBagConstraints();
		gbc_lblDirectory.gridwidth = 2;
		gbc_lblDirectory.anchor = GridBagConstraints.WEST;
		gbc_lblDirectory.insets = new Insets(0, 0, 5, 5);
		gbc_lblDirectory.gridx = 0;
		gbc_lblDirectory.gridy = 1;
		fileOptionsPanel.add(lblDirectory, gbc_lblDirectory);

		directoryField = new JTextField();
		directoryField.setPreferredSize(new Dimension(20, 20));
		directoryField.setText(DEFAULT_DIRECTORY);
		GridBagConstraints gbc_directoryField = new GridBagConstraints();
		gbc_directoryField.fill = GridBagConstraints.HORIZONTAL;
		gbc_directoryField.insets = new Insets(0, 2, 5, 5);
		gbc_directoryField.gridwidth = 4;
		gbc_directoryField.gridx = 0;
		gbc_directoryField.gridy = 2;
		fileOptionsPanel.add(directoryField, gbc_directoryField);
		directoryField.setColumns(10);

		JButton btnNewButton_1 = new JButton("...");
		btnNewButton_1.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				try{
					JFileChooser fileChooser = new JFileChooser();
					fileChooser.setCurrentDirectory(new File(directoryField.getText()));
					fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); 
					int returnVal = fileChooser.showOpenDialog(null);
					if(returnVal == JFileChooser.APPROVE_OPTION)
						directoryField.setText(fileChooser.getSelectedFile().toString());
				} catch (NullPointerException ex){

				}
			}
		});
		btnNewButton_1.setPreferredSize(new Dimension(23, 23));
		btnNewButton_1.setMinimumSize(new Dimension(23, 23));
		GridBagConstraints gbc_btnNewButton_1 = new GridBagConstraints();
		gbc_btnNewButton_1.anchor = GridBagConstraints.WEST;
		gbc_btnNewButton_1.insets = new Insets(0, 0, 5, 0);
		gbc_btnNewButton_1.gridx = 4;
		gbc_btnNewButton_1.gridy = 2;
		fileOptionsPanel.add(btnNewButton_1, gbc_btnNewButton_1);

		final JCheckBox openFileCheckBox = new JCheckBox("Open file on completion");
		GridBagConstraints gbc_openFileCheckBox = new GridBagConstraints();
		gbc_openFileCheckBox.gridwidth = 2;
		gbc_openFileCheckBox.insets = new Insets(0, 0, 5, 5);
		gbc_openFileCheckBox.gridx = 0;
		gbc_openFileCheckBox.gridy = 3;
		fileOptionsPanel.add(openFileCheckBox, gbc_openFileCheckBox);

		final DefaultListModel<WellCheckBox> wellListModel = new DefaultListModel<WellCheckBox>();

		final JCheckBox headerOutputCheckBox = new JCheckBox("Output headers");
		headerOutputCheckBox.setSelected(true);
		GridBagConstraints gbc_headerOutputCheckBox = new GridBagConstraints();
		gbc_headerOutputCheckBox.gridwidth = 2;
		gbc_headerOutputCheckBox.insets = new Insets(0, 0, 5, 5);
		gbc_headerOutputCheckBox.gridx = 2;
		gbc_headerOutputCheckBox.gridy = 3;
		fileOptionsPanel.add(headerOutputCheckBox, gbc_headerOutputCheckBox);

		JScrollPane scrollPane = new JScrollPane();
		GridBagConstraints gbc_scrollPane = new GridBagConstraints();
		gbc_scrollPane.fill = GridBagConstraints.BOTH;
		gbc_scrollPane.gridwidth = 5;
		gbc_scrollPane.insets = new Insets(0, 0, 5, 0);
		gbc_scrollPane.gridx = 0;
		gbc_scrollPane.gridy = 4;
		fileOptionsPanel.add(scrollPane, gbc_scrollPane);

		final JList<WellCheckBox> wellList = new JList<WellCheckBox>(wellListModel);
		scrollPane.setViewportView(wellList);
		wellList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);

		Button upButton = new Button("Up");

		GridBagConstraints gbc_upButton = new GridBagConstraints();
		gbc_upButton.anchor = GridBagConstraints.EAST;
		gbc_upButton.insets = new Insets(0, 0, 0, 5);
		gbc_upButton.gridx = 0;
		gbc_upButton.gridy = 5;
		fileOptionsPanel.add(upButton, gbc_upButton);

		Button downButton = new Button("Down");

		GridBagConstraints gbc_downButton = new GridBagConstraints();
		gbc_downButton.anchor = GridBagConstraints.WEST;
		gbc_downButton.insets = new Insets(0, 0, 0, 5);
		gbc_downButton.gridx = 1;
		gbc_downButton.gridy = 5;
		fileOptionsPanel.add(downButton, gbc_downButton);

		Button button = new Button("Remove");
		button.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				try{
					if(wellListModel.size()==0){
						statusField.setText("No items to remove.");
						return;
					}
					int selectedIndex = wellList.getSelectedIndex();
					WellCheckBox checkBoxToRemove = wellList.getSelectedValue();
					checkBoxToRemove.setSelected(false);
					wellListModel.removeElement(checkBoxToRemove);
					if(selectedIndex == wellListModel.getSize())
						wellList.setSelectedIndex(selectedIndex-1);
					else
						wellList.setSelectedIndex(selectedIndex);
					statusField.setText(DEFAULT_STATUS);
				} catch (NullPointerException ex){
					statusField.setText("Select an item in the list to remove.");
				}
			}
		});
		GridBagConstraints gbc_button = new GridBagConstraints();
		gbc_button.anchor = GridBagConstraints.WEST;
		gbc_button.insets = new Insets(0, 0, 0, 5);
		gbc_button.gridx = 2;
		gbc_button.gridy = 5;
		fileOptionsPanel.add(button, gbc_button);

		Button btnAddBlank = new Button("Add Blank");
		GridBagConstraints gbc_btnAddBlank = new GridBagConstraints();
		gbc_btnAddBlank.insets = new Insets(0, 0, 0, 5);
		gbc_btnAddBlank.gridx = 3;
		gbc_btnAddBlank.gridy = 5;
		fileOptionsPanel.add(btnAddBlank, gbc_btnAddBlank);
		btnAddBlank.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				wellListModel.addElement(new WellCheckBox());
			}
		});

		JPanel gridOptionsPanel = new JPanel();
		optionsPane.addTab("Grid Options", null, gridOptionsPanel, null);
		GridBagLayout gbl_gridOptionsPanel = new GridBagLayout();
		gbl_gridOptionsPanel.columnWidths = new int[] {26, 86, 40};
		gbl_gridOptionsPanel.rowHeights = new int[]{23, 0, 0, 0};
		gbl_gridOptionsPanel.columnWeights = new double[]{0.0, 0.0, 0.0};
		gbl_gridOptionsPanel.rowWeights = new double[]{0.0, 0.0, 0.0, Double.MIN_VALUE};
		gridOptionsPanel.setLayout(gbl_gridOptionsPanel);

		JLabel lblNewLabel = new JLabel("Rows");
		GridBagConstraints gbc_lblNewLabel = new GridBagConstraints();
		gbc_lblNewLabel.anchor = GridBagConstraints.WEST;
		gbc_lblNewLabel.insets = new Insets(0, 0, 0, 5);
		gbc_lblNewLabel.gridx = 0;
		gbc_lblNewLabel.gridy = 0;
		gridOptionsPanel.add(lblNewLabel, gbc_lblNewLabel);
		lblNewLabel.setHorizontalAlignment(SwingConstants.LEFT);

		wellRowCount = new JTextField();
		GridBagConstraints gbc_wellRowCount = new GridBagConstraints();
		gbc_wellRowCount.anchor = GridBagConstraints.WEST;
		gbc_wellRowCount.insets = new Insets(0, 0, 0, 5);
		gbc_wellRowCount.gridx = 1;
		gbc_wellRowCount.gridy = 0;
		gridOptionsPanel.add(wellRowCount, gbc_wellRowCount);
		wellRowCount.setText(String.valueOf(buttonPanelLayout.getRows()));
		wellRowCount.setColumns(10);

		JLabel lblNewLabel_1 = new JLabel("Columns");
		GridBagConstraints gbc_lblNewLabel_1 = new GridBagConstraints();
		gbc_lblNewLabel_1.anchor = GridBagConstraints.WEST;
		gbc_lblNewLabel_1.insets = new Insets(0, 0, 0, 5);
		gbc_lblNewLabel_1.gridx = 0;
		gbc_lblNewLabel_1.gridy = 1;
		gridOptionsPanel.add(lblNewLabel_1, gbc_lblNewLabel_1);

		wellColumnCount = new JTextField();
		GridBagConstraints gbc_wellColumnCount = new GridBagConstraints();
		gbc_wellColumnCount.anchor = GridBagConstraints.WEST;
		gbc_wellColumnCount.insets = new Insets(0, 0, 0, 5);
		gbc_wellColumnCount.gridx = 1;
		gbc_wellColumnCount.gridy = 1;
		gridOptionsPanel.add(wellColumnCount, gbc_wellColumnCount);
		wellColumnCount.setText(String.valueOf(buttonPanelLayout.getColumns()));
		wellColumnCount.setColumns(10);

		JButton btnNewButton = new JButton("Update");
		GridBagConstraints gbc_btnNewButton = new GridBagConstraints();
		gbc_btnNewButton.anchor = GridBagConstraints.NORTHWEST;
		gbc_btnNewButton.gridx = 0;
		gbc_btnNewButton.gridy = 2;
		gridOptionsPanel.add(btnNewButton, gbc_btnNewButton);

		JPanel statusPanel = new JPanel();
		statusPanel.setPreferredSize(new Dimension(10, 70));
		frmHelpingLily.getContentPane().add(statusPanel, BorderLayout.SOUTH);
		statusPanel.setLayout(new BoxLayout(statusPanel, BoxLayout.Y_AXIS));

		statusField = new JTextField();
		statusField.setPreferredSize(new Dimension(6, 10));
		statusPanel.add(statusField);
		statusField.setHorizontalAlignment(SwingConstants.CENTER);
		statusField.setText(DEFAULT_STATUS);
		statusField.setEditable(false);
		statusField.setColumns(10);

		final JProgressBar progressBar = new JProgressBar();
		statusPanel.add(progressBar);
		progressBar.setStringPainted(true);

		JButton btnImportFile = new JButton("Import File...");
		btnImportFile.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				//Open the open file dialog.
				if(!fileNameField.getText().matches("^([^\\s\\d])([^\\/:*?\"<>|.]|)+")){
					statusField.setText("Invalid file name.");
					return;
				}
				JFileChooser fileChooser = new JFileChooser();
				BufferedWriter outputStream = null;
				File outputFile = null;
				fileChooser.setCurrentDirectory(new File(DEFAULT_DIRECTORY));
				fileChooser.showOpenDialog(null);
				try{

					statusField.setText("Analyzing file.");
					progressBar.setValue(25);
					FileAnalyzer a = new FileAnalyzer(fileChooser.getSelectedFile());
					statusField.setText("File analysis complete.");
					progressBar.setValue(50);
					Vector<ReadingSet> allReadingSets = a.getReadingSets();
					String fileName;
					if(!fileNameField.getText().equals("")){
						fileName = fileNameField.getText() + ".csv";    
					}else{
						fileName = "test.csv";
					}
					outputStream = new BufferedWriter(new FileWriter(outputFile = new File(new File(directoryField.getText()).getPath()+File.separator+fileName)));
					statusField.setText("Outputting formatted data.");
					progressBar.setValue(75);
					//Output the headers.
					if(headerOutputCheckBox.isSelected()){
						for (int i=0; i<wellListModel.size(); i++){
							if(wellListModel.get(i).isSelected()){
								if(wellListModel.get(i).getWellNumber()>0){
									outputStream.write("Well "+wellListModel.get(i).getWellNumber());
								} 
								outputStream.write(",");
							} else if(wellListModel.get(i).getWellNumber()<0){
								outputStream.write(",");
							}       
						}
						outputStream.newLine();
					}
					//Output the data.
					for(ReadingSet r : allReadingSets){
						for (int i=0; i<wellListModel.size(); i++){
							if(wellListModel.get(i).isSelected()){
								outputStream.write(r.getWellData(wellListModel.get(i).getRowNumber(), wellListModel.get(i).getColNumber()).toString());
								outputStream.write(",");
							} else if(wellListModel.get(i).getWellNumber()<0){
								outputStream.write(",");
							}
						}
						outputStream.newLine();
					}
					statusField.setText("Complete.");
					progressBar.setValue(100);

				}catch(NullPointerException e){
					System.out.println("Couldn't retrieve file...");
					statusField.setText(DEFAULT_STATUS);
					progressBar.setValue(0);
				}catch(IOException e){
					statusField.setText("Couldn't open file. (Is it already open?)");
					progressBar.setValue(0);
				}finally{
					try {
						outputStream.close();
						if(openFileCheckBox.isSelected()){
							Desktop dt = Desktop.getDesktop();
							dt.open(outputFile);
						}
					} catch (NullPointerException | IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					} catch (UnsupportedOperationException e){
						statusField.setText("File opening is not supported on this environment.");
					} catch (Exception e){
						statusField.setText("There was an error.");
					}
				}
			}
		});
		upButton.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				try{
					Integer selectedIndex = wellList.getSelectedIndex();
					statusField.setText(DEFAULT_STATUS);
					progressBar.setValue(0);
					if(wellListModel.size()==1 || selectedIndex.equals(0))
						return;
					wellListModel.add(selectedIndex-1, wellListModel.get(selectedIndex));
					wellListModel.remove(selectedIndex+1);
					wellList.setSelectedIndex(selectedIndex-1);
				}catch (ArrayIndexOutOfBoundsException ex){
					statusField.setText("An item must be selected.");
				}
			}
		});
		downButton.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				try{
					Integer selectedIndex = wellList.getSelectedIndex();
					statusField.setText(DEFAULT_STATUS);
					progressBar.setValue(0);
					if(wellListModel.size()==1 || selectedIndex.equals(wellListModel.size()-1))
						return;
					wellListModel.add(selectedIndex, wellListModel.get(selectedIndex+1));
					wellListModel.remove(selectedIndex+2);
					wellList.setSelectedIndex(selectedIndex+1);
				}catch (ArrayIndexOutOfBoundsException ex){
					statusField.setText("An item must be selected.");
				}
			}
		});
		btnImportFile.setAlignmentX(Component.CENTER_ALIGNMENT);
		btnImportFile.setMaximumSize(new Dimension(6516, 6516));
		statusPanel.add(btnImportFile);
		btnNewButton.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				Integer wellRows = Integer.valueOf(wellRowCount.getText());
				Integer wellColumns = Integer.valueOf(wellColumnCount.getText());
				buttonPanelLayout.setRows(wellRows);
				buttonPanelLayout.setColumns(wellColumns);
				buttonPanel.removeAll();
				for(int i=1;i<=wellRows;i++){
					for (int j=1;j<=wellColumns;j++){
						Integer checkBoxNumber = (i-1)*wellColumns+j;
						WellCheckBox checkBox = new WellCheckBox("checkBox_",checkBoxNumber,i,j);
						buttonPanel.add(checkBox);
						allCheckboxes.add(checkBox);
					}
				}
				wellListModel.clear();
				buttonPanel.updateUI();
			}
		});
		for (final WellCheckBox w : allCheckboxes){
			w.addActionListener(new ActionListener() {
				@Override
				public void actionPerformed(ActionEvent e) {
					statusField.setText(DEFAULT_STATUS);
					progressBar.setValue(0);

					//If a checkbox is selected add its name to the list.
					if(w.isSelected()){
						wellListModel.addElement(w);
					}else{
						wellListModel.removeElement(w);
					}
				}
			});
		}
		deselectAllMenuItem.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				for (WellCheckBox w : allCheckboxes){
					w.setSelected(false);
					wellListModel.removeElement(w);
				}
			}
		});
		selectAllMenuItem.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				for (WellCheckBox w : allCheckboxes){
					w.setSelected(true);
					wellListModel.addElement(w);
				}
			}
		});
		mntmSaveConfiguration.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				JFileChooser fileChooser = new JFileChooser(directoryField.getText()+File.separator+"config");
				fileChooser.setFileFilter(new ConfigurationFileFilter());
				fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
				int returnVal = fileChooser.showSaveDialog(null);
				if(returnVal == JFileChooser.CANCEL_OPTION)
					return;
				File configurationFile = fileChooser.getSelectedFile();
				if(!ConfigurationFileFilter.hasExtension(configurationFile, "cfg")){
					configurationFile = new File(configurationFile.toString() + ".cfg");
				}
				ObjectOutputStream objectWriter = null;
				try {
					objectWriter = new ObjectOutputStream(new FileOutputStream(configurationFile));
					objectWriter.writeObject(wellListModel);
					objectWriter.writeObject(allCheckboxes);
				} catch (IOException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				} finally {
					try {
						objectWriter.close();
					} catch (IOException e1) {
						// TODO Auto-generated catch block
						e1.printStackTrace();
					}
				}
			}
		});
		mntmOpenConfiguration.addActionListener(new ActionListener() {
			@Override
			@SuppressWarnings("unchecked")
			public void actionPerformed(ActionEvent e) {
				JFileChooser fileChooser = new JFileChooser(directoryField.getText()+File.separator+"config");
				fileChooser.setFileFilter(new ConfigurationFileFilter());
				fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
				int returnVal = fileChooser.showOpenDialog(null);
				if(returnVal == JFileChooser.CANCEL_OPTION)
					return;
				File configurationFile = fileChooser.getSelectedFile();
				ObjectInputStream objectReader = null;
				try {
					objectReader = new ObjectInputStream(new FileInputStream(configurationFile));
					DefaultListModel<WellCheckBox> newWellListModel = (DefaultListModel<WellCheckBox>) objectReader.readObject();
					Vector<WellCheckBox> newAllCheckboxes = (Vector<WellCheckBox>) objectReader.readObject();
					wellListModel.clear();
					allCheckboxes.clear();
					buttonPanel.removeAll();
					for(int i=0;i<newWellListModel.getSize();i++){
						wellListModel.addElement(newWellListModel.get(i));
					}
					for(final WellCheckBox w : newAllCheckboxes){
						buttonPanel.add(w);
						allCheckboxes.addElement(w);
						w.addActionListener(new ActionListener() {
							@Override
							public void actionPerformed(ActionEvent e) {
								statusField.setText(DEFAULT_STATUS);
								progressBar.setValue(0);

								//If a checkbox is selected add its name to the list.
								if(w.isSelected()){
									wellListModel.addElement(w);
								}else{
									wellListModel.removeElement(w);
								}
							}
						});
					}
					for (final WellCheckBox w : allCheckboxes){
						w.addActionListener(new ActionListener() {
							@Override
							public void actionPerformed(ActionEvent e) {
								statusField.setText(DEFAULT_STATUS);
								progressBar.setValue(0);

								//If a checkbox is selected add its name to the list.
								if(w.isSelected()){
									wellListModel.addElement(w);
								}else{
									wellListModel.removeElement(w);
								}
							}
						});
					}
					buttonPanel.updateUI();
					
				} catch (IOException | ClassNotFoundException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				} catch (NullPointerException e1){
					
				} finally {
					try {
						objectReader.close();
					} catch (IOException e1) {
						// TODO Auto-generated catch block
						e1.printStackTrace();
					} catch (NullPointerException e1){
						
					}
				}
			}
		});
		mntmNewMenuItem.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				for(WellCheckBox w : allCheckboxes){
					w.setSelected(false);
					wellListModel.clear();
				}
			}
		});
	}

}
